#ifndef NctiRenderFonts_H
#define NctiRenderFonts_H
#include "NctiRenderItem.h"
#include "string"
#include "vector"
#include "array"
#include "ft2build.h"
#include FT_FREETYPE_H
#include <wchar.h>
namespace NCTI
{
    /**
     * @brief internal usage
     */
    struct DECL_NCTI_RENDER NctiCharacter
    {
        std::vector<unsigned char> image;
        int startx{ -1 }, starty{ -1 };
        int sizex{ 0 }, sizey{ 0 };
        float bearX{ 0 }, bearY{ 0 };
        float advance{0};
    };

    class NctiRenderTextItem;
    class DECL_NCTI_RENDER NctiRenderFonts : public NctiRenderItem
    {
        NCTI_RENDER_FUNCTIONS(NctiRenderFonts)
    public:

        /**
         * @brief construct
         * @param[in] i_FontsName font name
         */
        NctiRenderFonts(const std::string& i_FontsName);
        virtual ~NctiRenderFonts();

        /**
         * @brief init the font
         * @param[in] i_ft the free type object
         * @param[in] i_FontsFileName the font file
         */
        Ncti_Boolean InitFont(FT_Library i_ft, const char* i_FontsFileName);

        /**
         * @brief completion virtual function
         * @details reset the associate text object modify state
         */
        void ResetModify(NctiViewerRenderer* i_pViewerRenderer)override;

        /**
         * @brief get font name
         */
        const std::string& GetFontsName()const;

        /**
         * @brief get font file
         */
        const std::string& GetFontFile()const;

        /**
         * @brief update the font word
         * @param[in] str text to be display
         * @return the string length
         */
        float UpdateString(std::wstring str);

        /**
         * @brief update the font word
         * @param[in] i_c char to be display
         * @return the character
         */
        NctiCharacter* TouchCharacter(Ncti_WChar i_c);

        /**
         * @brief update the font word
         * @param[in] i_c char to be display
         * @return the character
         */
        void DetachAllItem();

        /**
         * @brief detach the text item from the font
         * @param[in] text text to be display
         */
        void DetachTextItem(NctiRenderTextItem* text);

        /**
         * @brief Attach the text item to the font
         * @param[in] text text to be display
         */
        void AttachTextItem(NctiRenderTextItem*);

        /**
         * @brief get the font image width
         * @details internal usage
         */
        int GetWidth()const;

        /**
         * @brief get the font image buffer
         * @details internal usage
         */
        const std::vector<unsigned char>& GetBuffer()const;

    private:
        void DealCharacter();
        float LoadFontRes = 48.0;
        std::string m_file;
        std::string m_FontsName;
        FT_Face m_FT_Face{ nullptr };
        std::array<NctiCharacter*, 65535>m_CharacterVec{};
        Ncti_UInteger m_MaxWH{ 0 };
        Ncti_UInteger m_num{ 0 };
        std::vector<unsigned char> m_Allbuffer;
        int m_width{ 0 };

        Ncti_Boolean m_Charchange{ true };
        std::vector<NctiRenderTextItem*>m_attach;
    };
}
#endif
